package com.chenl.provider.util;

import com.alibaba.fastjson.JSONObject;
import com.chenl.provider.DTO.vo.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * redis工具类接口,外放一个接口,直接通过postman就可以方便增删查缓存
 * 1。type ：         类型   （String，hash，list。。。）
 * 2. operateType：   操作类型 增 1 删 2  改  3  查  4
 * 3. key    :        redisKey
 * 4. hashkey        使用hash类型的时候传入即可，不使用hash时传入也不碍事，不用每次都删除
 * 5. value  :       redisValue
 *  不需要设置时间,以下都不传  OR   6 7任意一个 传空字符串或者不传 都可以
 * 6. expireTime :   过期时间
 * 7. timeType  :    过期时间单位(sec min hour day)
 *      范例参数:
 * {
 *     "type":"string",
 *     "operateType":"6",
 *     "key":"*",
 *     "hashkey":"",
 *     "value":"Min",
 *     "expireTime":"",
 *     "timeType":""
 * }
 *
 */
@RestController
@RequestMapping("/redisControl")
public class RedisController {
    @Autowired
    RedisService redisService;
    @Resource(name = "MyRedisTemplate")
    RedisTemplate redisTemplate;

    @PostMapping("/redis")
    public Result<Object> redisControl(@RequestBody JSONObject jsonObject) {
        String type = jsonObject.getString("type");//redis  类型（String，hash，list。。。）
        if (!StringUtils.isBlank(type)) {
            String hashkey = jsonObject.getString("hashkey");//hashKey
            if (type.equalsIgnoreCase("hash")){
                if (StringUtils.isBlank(hashkey)){
                    return  new Result<>("操作hash类型时，hashKey不能为空");
                }
            }
            Integer operateType = jsonObject.getInteger("operateType");//操作类型
            String key = jsonObject.getString("key");//redisKey
            Object value = jsonObject.get("value");//value
            Long expireTime = jsonObject.getLong("expireTime");//过期时间
            String timeType = jsonObject.getString("timeType");//时间类型  sec min hour day
            // TimeUnit.SECONDS   TimeUnit.MINUTES  TimeUnit.HOURS  TimeUnit.DAYS
            if (operateType==1){//增
              redisSave(type,key,hashkey,value,expireTime,timeType);
            }else if (operateType==2){//删
              redisDelete(type,key,hashkey);
            }else if (operateType==3){//改
                redisSave(type,key,hashkey,value,expireTime,timeType);
            }else if (operateType==4){//查
                Object o = redisQuery(type,key, hashkey);
                return new Result<>(o);
            }else if (operateType==5){//根据key进行模糊查询,如传入*abc ,则查看所有以abc结尾的key
                Set<String> strings = redisService.sCan(key);
                return new Result<>(strings);
            }
            else if (operateType==6){//根据value模糊查询key
                List<String> list = redisService.selectKeysByValue(String.valueOf(value));
                return new Result<>(list);
            }
        } else {
            return new Result<>("type不可以为空！");
        }
        return new Result<>();
    }

    private Object redisQuery(String type,String key, String hashkey) {
        if (type.equalsIgnoreCase("hash")){
            return this.redisTemplate.opsForHash().get(key,hashkey);
        }else {
            return this.redisTemplate.opsForValue().get(key);
        }
    }

    private void redisDelete(String type, String key, String hashkey) {
        if (type.equalsIgnoreCase("string")||type.equalsIgnoreCase("list")){
            this.redisTemplate.delete(key);
        }
        else if (type.equalsIgnoreCase("hash")){
            this.redisTemplate.opsForHash().delete(key,hashkey);
        }
    }

    private void redisSave(String type, String key, String hashkey, Object value, Long expireTime, String timeType) {
        if (type.equalsIgnoreCase("string")){
            if (!String.valueOf(expireTime).equals("null")&&StringUtils.isNotBlank(String.valueOf(expireTime))&&StringUtils.isNotBlank(timeType)){
                switch (timeType){
                    case "sec":
                        this.redisTemplate.opsForValue().set(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);
                        break;
                    case "min":
                        this.redisTemplate.opsForValue().set(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.MINUTES);
                        break;
                    case "hour":
                        this.redisTemplate.opsForValue().set(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.HOURS);
                        break;
                    case "day":
                        this.redisTemplate.opsForValue().set(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.DAYS);
                        break;
                }
            }else {
                 this.redisTemplate.opsForValue().set(key,value);
            }
        }else if (type.equalsIgnoreCase("list")){
            if (StringUtils.isNotBlank(String.valueOf(expireTime))&&StringUtils.isNotBlank(timeType)){
                switch (timeType){
                    case "sec":
                        this.redisTemplate.opsForList().leftPush(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);
                        break;
                    case "min":
                        this.redisTemplate.opsForList().leftPush(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.MINUTES);
                        break;
                    case "hour":
                        this.redisTemplate.opsForList().leftPush(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.HOURS);
                        break;
                    case "day":
                        this.redisTemplate.opsForList().leftPush(key,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.DAYS);
                        break;
                }
            }else {
                this.redisTemplate.opsForList().leftPush(key,value);
            }
        }else if (type.equalsIgnoreCase("hash")){
            if (StringUtils.isNotBlank(String.valueOf(expireTime))&&StringUtils.isNotBlank(timeType)){
                switch (timeType){
                    case "sec":
                        this.redisTemplate.opsForHash().put(key,hashkey,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.SECONDS);
                        break;
                    case "min":
                        this.redisTemplate.opsForHash().put(key,hashkey,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.MINUTES);
                        break;
                    case "hour":
                        this.redisTemplate.opsForHash().put(key,hashkey,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.HOURS);
                        break;
                    case "day":
                        this.redisTemplate.opsForHash().put(key,hashkey,value);
                        this.redisTemplate.expire(key,expireTime,TimeUnit.DAYS);
                        break;
                }
            }else {
                this.redisTemplate.opsForHash().put(key,hashkey,value);
            }
        }
    }
}